# Extracting GraphQL Definitions from Code Files

`@graphql-tools/graphql-tag-pluck` will take JavaScript code as an input and will pluck all template
literals provided to `graphql-tag`.

```js filename="Input"
import gql from 'graphql-tag'

const fragment = gql`
  fragment Foo on FooType {
    id
  }
`

const doc = gql`
  query foo {
    foo {
      ...Foo
    }
  }

  ${fragment}
`
```

```graphql filename="Output"
fragment Foo on FooType {
  id
}

query foo {
  foo {
    ...Foo
  }
}
```

Originally created because of https://graphql-code-generator.com.

## Usage

```sh npm2yarn
npm i @graphql-tools/graphql-tag-pluck
```

Once installed you can pluck GraphQL template literals using one of the following methods:

```js
import {
  gqlPluckFromCodeString,
  gqlPluckFromCodeStringSync
} from '@graphql-tools/graphql-tag-pluck'

// Returns promise
gqlPluckFromCodeString(
  filePath, // this parameter is required to detect file type
  fs.readFileSync(filePath, 'utf8')
)

// Returns string
gqlPluckFromCodeStringSync(filePath, fs.readFileSync(filePath, 'utf8'))
```

Template literals leaded by magic comments will also be extracted :-)

```js
const MessageType = /* GraphQL */ `
  enum MessageType {
    text
    media
    draftjs
  }
`
```

Supported file extensions are:

- `.js`
- `.mjs`
- `.cjs`
- `.jsx`
- `.ts`
- `.mts`
- `.cts`
- `.tsx`
- `.flow`
- `.flow.js`
- `.flow.jsx`
- `.vue`
- `.svelte`
- `.astro`

## Options

It is recommended to look at the
[source code](https://github.com/ardatan/graphql-tools/blob/master/packages/graphql-tag-pluck/src/visitor.ts)
for a clearer understanding of the transformation options.

### `gqlMagicComment`

The magic comment anchor to look for when parsing GraphQL strings. Defaults to `graphql`, which may
be translated into `/* GraphQL */` in code.

### `globalGqlIdentifierName`

Allows using a global identifier instead of a module import. Identifiers are case sensitive.

```js
// `graphql` is a global function
export const usersQuery = graphql`
  {
    users {
      id
      name
    }
  }
`
```

### `modules`

An array of packages that are responsible for exporting the GraphQL string parser function.

The following modules are supported by default:

```js
{
  modules: [
    // import gql from 'graphql-tag'
    { name: 'graphql-tag' },
    { name: 'graphql-tag.macro' },
    // import { graphql } from 'gatsby'
    { identifier: 'graphql', name: 'gatsby' },
    { identifier: 'gql', name: 'apollo-server-express' },
    { identifier: 'gql', name: 'apollo-server' },
    { identifier: 'graphql', name: 'react-relay' },
    { identifier: 'gql', name: 'apollo-boost' },
    { identifier: 'gql', name: 'apollo-server-koa' },
    { identifier: 'gql', name: 'apollo-server-hapi' },
    { identifier: 'gql', name: 'apollo-server-fastify' },
    { identifier: 'gql', name: 'apollo-server-lambda' },
    { identifier: 'gql', name: 'apollo-server-micro' },
    { identifier: 'gql', name: 'apollo-server-azure-functions' },
    { identifier: 'gql', name: 'apollo-server-cloud-functions' },
    { identifier: 'gql', name: 'apollo-server-cloudflare' }
  ]
}
```

### `isGqlTemplateLiteral`

A custom way to determine if a template literal node contains a GraphQL query.

By default, it checks if the leading comment is equal to the `gqlMagicComment` option.

```js
function isGqlTemplateLiteral(node, options) {
  // Check if the template literal starts with `#graphql` comment
  return node.type === 'TemplateLiteral' && node.quasis[0]?.value?.raw?.startsWith('#graphql')
}
```

### `pluckStringFromFile`

A function that allows custom extraction of GraphQL strings from a file.

```js
function pluckStringFromFile(code, { start, end, leadingComments }) {
  // Slice quotes and remove inner comment
  return code.slice(start + 1, end - 1).replace('#graphql\n', '')
}
```
